/*****CONSTANTS******/
var _SEL	= "SELECT";
var _INP	= "INPUT";
var _A		= "A";
var _RES	= "RESET";
var _SUB	= "SUBMIT";
var _BUT	= "BUTTON";
var _TEXTAREA	= "TEXTAREA";
var _IMG		= "IMG";

var _TYPE_IMA	= "IMAGE";
var _TYPE_RAD	= "RADIO";
var _TYPE_TEXT	= "TEXT";
var _TYPE_PASSWORD	= "PASSWORD";


var _LEAVE	= "leave";
var _ENTER	= "enter";

var _TAB	= 9;
var _SEP	= '|';
var _SPA		= ' ';
var _UNDEF	= '-';
var _L_BRA	= '[';
var _R_BRA	= ']';
var _BR	= "\n";

/*****config variables******/
var IS_DEBUG	= true;
var IS_PRINT	= false;
var DEBUG_LEVEL	= 10;

var _IS_SEND	= true;
var _PROXY_SERVER	= 'http://localhost:8080/tuin_proxy/clientTraceWriter.jsp';

/*****global variables******/
var user_interaction_history = '';
var pre_event	= null;

/*****functions******/

/**tag detection functions*/
function isUndefinied(tag_name){
	return (tag_name === undefined);
}

function is_input_tag(tag_name){
	if ( isUndefinied(tag_name) ) return false;
	return tag_name.toUpperCase() == _INP;
}

function is_select_tag(tag_name){
	if ( isUndefinied(tag_name) ) return false;
	return tag_name.toUpperCase() == _SEL;
}

function is_textarea_tag(tag_name){
	if ( isUndefinied(tag_name) ) return false;
	return tag_name.toUpperCase() == _TEXTAREA;
}

function is_A_tag(tag_name){
	if ( isUndefinied(tag_name) ) return false;
	return tag_name.toUpperCase() == _A;
}


function is_img_tag(tag_name){
	if ( isUndefinied(tag_name) ) return false;
	return tag_name.toUpperCase() == _IMG;

}

function is_input_image(tType){
	if ( isUndefinied(tType) ) return false;
	return tType.toUpperCase() == _TYPE_IMA;	
}

function is_input_radio(tType){
	if ( isUndefinied(tType) ) return false;
	return tType.toUpperCase() == _TYPE_RAD;
}

function is_input_text(tType){
	if ( isUndefinied(tType) ) return false;
	return tType.toUpperCase() == _TYPE_TEXT;	
}

function is_input_password(tType){
	if ( isUndefinied(tType) ) return false;
	return tType.toUpperCase() == _TYPE_PASSWORD;	
}


function has_A_ancestor(target_ele){
	var ancTags	= getAncTagList(target_ele);
	
	debug( target_ele + ' ancTag: ' + ancTags, 4 );
	return (ancTags.indexOf(bracket(_A)) !=-1);
}
/**tag detection functions end*/


/**event, element, tag functions*/
function getTarEle(e){
	var targetElement = e.target; 

	if( targetElement && ( targetElement.nodeType == 3 ) ) {
		targetElement = targetElement.parentNode; 
	}
	return targetElement;
}

function formatUndef(target){
	if ( target === undefined || target.length==0 )
	{
		return _UNDEF;
	}else{
		return target;
	}
}

function getAncestors(ele, anc) { 
	if (ele.parentNode) { 
		var pNode	= ele.parentNode;
		debug( pNode.tagName, 1 );
		anc.push(formatUndef(pNode.name) + _SEP + formatUndef(pNode.tagName)); 
		getAncestors(ele.parentNode, anc); 
	} 
} 

function getAncNameList(element){
	var anc = []; 
	getAncestors(element, anc);
	
	var ancList = '';
	for (index in anc){
		var ancName		= _UNDEF;
		if (anc[index]) ancName = anc[index];
		ancList += bracket(ancName);
	}
	return ancList;
}


function getAncestorTags(element, anc) { 
	if (element.parentNode.tagName != null) { 
		debug('get anc tag', 3);
		anc.push(element.parentNode.tagName); 
		getAncestorTags(element.parentNode, anc); 
	} 
}

function getAncTagList(element){
	var anc = []; 

	getAncestorTags(element, anc);
	
	var ancList = '';
	for (index in anc){
		var ancTag		= _UNDEF;
		if (anc[index]) ancTag = anc[index];
		ancList = bracket(ancTag) + ancList;
	}
	return ancList;
}
/**event, element, tag functions end*/


/** util functions */
function debug(msg, level){
	if (IS_DEBUG && level == DEBUG_LEVEL )
	{
		alert(msg);
	}
}

function construct_time_stamp(){
	var millisce	= new Date().getTime();//Number(new Date());
	var time		= new Date().toLocaleString();

	return bracket(millisce) + _SPA + bracket(time);
}

function construct_request_url(){
	return _PROXY_SERVER;
}

function construct_user_hist_query(){
	return 'userHistory=' + encodeURIComponent(user_interaction_history);
}

//synchronous
function log_user_interaction(event, target_ele, target_name, time_stamp){
	var full_name	= bracket(target_name) + getAncNameList(target_ele);		
	
	var url	= window.location.pathname;
	var user_interaction = time_stamp + _SPA + event.type + _SPA + bracket(url) + _SPA + full_name;

	user_interaction_history	+= user_interaction;
	
	if (IS_DEBUG && IS_PRINT)	{	
		document.getElementById( "t-area" ).value = user_interaction_history + '\n';
	}

	send_request(true);
}

function bracket(name){
	return _L_BRA + name + _R_BRA;
}

function send_request(flag){
	if (!_IS_SEND)
	{
		user_interaction_history = '';
		return;
	}

	var request = false;
	try {
		request = new XMLHttpRequest();

	} catch (trymicrosoft) {
		try {
			request = new ActiveXObject("Msxml2.XMLHTTP");
		}catch (othermicrosoft) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				request = false;
			}
		}
	}

	if (request==null){
		return;
	}

	request.onreadystatechange = null;
	request.abort();

	var url		= construct_request_url();
	var query	= construct_user_hist_query();
	
	user_interaction_history = '';
	//GET METHOD
	/* */
	var msg	= url + '?' + query;
	debug ( 'send :' + msg, 1 );
	request.open('GET', msg, flag);
	request.send(null);
	
	debug ( 'done!', 9 );
	
	/*
	//POST METHOD doesn't work on gatech medical for unknown reason.
	debug ( 'send to ' + url + ' w/' + query, 1 );
	request.open('POST', url, flag);
	
	//Send the proper header information along with the request
	request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	request.setRequestHeader('Content-length', query.length);
	request.setRequestHeader('Connection', 'close');

	request.send(query);
	debug ( 'done!' );
	*/
	
}
/** util functions end*/

/** hanlder functions */
/**
	
*/
function common_handler(e) { 	
	var time_stamp	= construct_time_stamp();	
	
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;

	if ( tag_name == null && target_ele.name == null )		return;
	debug( tag_name );
	if ( is_A_tag(tag_name) || has_A_ancestor(target_ele) || is_img_tag(tag_name) || is_select_tag(tag_name) || is_input_tag( tag_name ) )  return;
	
	var target_name	= formatUndef(target_ele.name) + _SEP + tag_name;
	
	log_user_interaction(e, target_ele, target_name, time_stamp);
}


function input_handler(e){
	var time_stamp	= construct_time_stamp();		
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;

	if ( tag_name == null && target_ele.name == null )		return;
	if ( !is_input_tag( tag_name ) )  return;

	if ( is_input_radio(target_ele.type) )
	{
		debug( 'input radio', 9 );
	}else{
		debug( 'not input radio', 9 )
	}
	var target_name	= formatUndef(target_ele.name) + _SEP + tag_name + _SEP + target_ele.type;
	
	if (target_ele.value != null && target_ele.value.length > 0) 
		target_name += _SEP + target_ele.value;
				
	if (is_input_image (target_ele.type) )		
		target_name += _SEP + target_ele.src;		
	
	
	debug( 'input radio u_i logged: ' + user_interaction_history, 9 );
	log_user_interaction(e, target_ele, target_name, time_stamp);
}

/**
 * Specific for select element.
 * @param event on select element.
 * @return
*/
function select_handler(e){		
	var time_stamp	= construct_time_stamp();	
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;
	
	if ( !is_select_tag(tag_name) ) return;
	
	var select_value	= target_ele.options[target_ele.selectedIndex].value;
	var target_name		= formatUndef(target_ele.name) + _SEP + formatUndef(select_value) + _SEP + tag_name;; 

	if (target_name != null&& target_name.length > 0)	{
		log_user_interaction(e, target_ele, target_name, time_stamp);
	}
}

/**
 * Specific for A element
 * @param e
 * @return
 */
function A_handler(e){
	var time_stamp	= construct_time_stamp();	
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;
	
	if ( !is_A_tag(tag_name) && !has_A_ancestor(target_ele) ) 	return;
	
	var target_name	= formatUndef(target_ele.name);
	if ( is_A_tag(tag_name) )	{
		target_name	+= _SEP  + target_ele.innerHTML + _SEP  + target_ele.getAttribute('href');
		debug ( 'A', 4 );
	}else if ( has_A_ancestor(target_ele) ){
		function find_A_anc(ele){
			var pNode	= ele.parentNode;
			if ( !is_A_tag(pNode.tagName ) )	
				return find_A_anc(ele.parentNode);
			else 
				return pNode;
		}

		var A_anc	= find_A_anc(target_ele);

		debug( 'A_anc: ' + A_anc );
		target_name	+= _SEP + A_anc.innerHTML  + _SEP + A_anc.getAttribute('href')  ;

		debug( 'A_anc ' + target_name, 4 );
	}
	
	debug('click tag: ' + target_name, 4 );
	log_user_interaction(e, target_ele, target_name, time_stamp);
}

/**
 * For IMG element
 */
function img_hanlder(e){
	var time_stamp	= construct_time_stamp();	
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;

	if ( !is_img_tag(tag_name) ) return;
	if ( has_A_ancestor(target_ele) ) return;

	debug( 'image', 4 );

	var target_name	= formatUndef(target_ele.name) + _SEP + tag_name + _SEP + target_ele.src;
	log_user_interaction(e, target_ele, target_name, time_stamp);
}

function textarea_handler(e){
	var time_stamp	= construct_time_stamp();	
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;

	if ( !is_textarea_tag(tag_name) ) return;

	debug( 'text area', 8 );
	var target_name	= formatUndef(target_ele.name) + _SEP + tag_name + _SEP + target_ele.value;

	log_user_interaction(e, target_ele, target_name, time_stamp);
}
/** hanlder functions end*/


/** loading functions */
function focus_handler(e){
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;
	
	if ( !is_textarea_tag(tag_name) && !is_input_tag(tag_name) )
	{
		return;
	}

	debug( 'textarea or input', 8 );

	if ( is_textarea_tag(tag_name) )
	{
		textarea_handler(e);
	}else if ( is_input_text(target_ele.type) || is_input_password(target_ele.type) )
	{
		input_handler(e);
	}else {
		return;
	}
}

function blur_handler(e){
	var target_ele	= getTarEle(e);
	var tag_name	= target_ele.tagName;
	
	if ( !is_textarea_tag(tag_name) && !is_input_tag(tag_name) )
	{
		return;
	}

	debug( 'textarea or input', 8 );

	if ( is_textarea_tag(tag_name) )
	{
		textarea_handler(e);
	}else if ( is_input_text(target_ele.type) || is_input_password(target_ele.type) )
	{
		input_handler(e);
	}else {
		return;
	}

}


function change_handler(e){
	select_handler(e);
}

function click_hanlder(e){
	var target_ele	= getTarEle(e);
	if ( is_input_text(target_ele.type) || is_input_password(target_ele.type))
	{
	}else{	
		input_handler(e);
	}
	A_handler(e);
	textarea_handler(e);
	img_hanlder(e);
	//select_handler(e);
}

function add_load_handlers(){
	//entering log item
	var time_stamp				= construct_time_stamp();		
	user_interaction_history	= _BR + time_stamp + _SPA + _ENTER + _SPA + bracket(window.location.pathname);
	send_request(true);

	debug( 'adding handlers', 7 );

	window.addEventListener('focus', focus_handler, true);
	//window.addEventListener('blur', blur_handler, true);
	window.addEventListener('change', change_handler, true);
	window.addEventListener('click', click_hanlder, true);

	debug( 'handlers added', 7 );
}

function add_beforeunload_handler(){
	var time_stamp		= construct_time_stamp();	
	user_interaction_history = time_stamp + _SPA + _LEAVE + _SPA + bracket(window.location.pathname);	
	//leaving log item
	send_request(false);
}

/** loading functions end*/


window.addEventListener('load', add_load_handlers, true);
window.addEventListener('beforeunload', add_beforeunload_handler, true);